Release 10.1A: OpenEdge Development:
Progress 4GL Handbook
Running a procedure PERSISTENT
For all these reasons, Progress lets you run a procedure so that it stays in memory for as long as you need it, without it being dependent on, or in any way subordinate to, the procedure that runs it. A procedure run in this way is called a persistent procedure. You use this syntax to run it:
The
PERSISTENTkeyword in the statement tells Progress to start the procedure and to leave it in memory, either until you delete it or until your session ends.Optionally, you can use the
SETphrase to save off the handle of the new procedure. You’ve seen handle variables already. Of particular significance is that persistent procedures have handles the same as other objects do, so that you can access them after they’ve been instantiated by aRUN PERSISTENTstatement. In fact, even a procedure that you run without thePERSISTENToption has a handle, but you would rarely use it. As noted above, the calling procedure can’t really execute any code until the procedure it runs terminates, and when that happens the subprocedure’s handle goes away, so the calling procedure would never really have a chance to use it.In practice, you will almost always use the
SETproc-handleoption, because the way you make use of a persistent procedure is to initiate it with aRUNstatement and then to use its handle afterwards to run entry points inside it. Theproc-handlemust be a variable or temp-table field with theHANDLEdata type, defined or accessible in the calling procedure.THIS-PROCEDURE built-in function
Whenever you run a procedure, persistent or not, you can retrieve its procedure handle using the built-in function
THIS-PROCEDURE. This is useful when you want to access attributes or methods of the current procedure. There are some examples of this later in the "Useful procedure attributes and methods" section.In most cases, you use procedure handles and the
THIS-PROCEDUREfunction when you run persistent procedures. However, keep in mind that every running procedure, whether it is persistent or not, has a procedure handle that is held inTHIS-PROCEDURE. A non-persistent procedure can passTHIS-PROCEDUREas anINPUTparameter to anther procedure, and the subprocedure can use that value to access internal procedures and other elements of the parent procedure. This is definitely not the norm for programming with procedure handles, but you can use it as a way to pass procedures down through a call stack, as the following example shows. This parent procedure passes its own procedure handle to another procedure as a parameter:
The child procedure can then use the parent’s handle to run the internal procedure in the parent:
The message shown in Figure 13–3 results.
Figure 13–3: Message result of childproc.p
![]()
This technique has limited usefulness, because there is no way for the parent to access internal procedures or other elements of the child procedure it runs. Only the child can access the parent procedures’s information.
Instantiating the persistent procedure
What happens when you run a procedure
PERSISTENT? You already know that a procedure has a main block, which has all the code and definitions that are scoped to the procedure itself. Another way of saying this is that this is everything in the procedure file that isn’t in an internal procedure or a trigger. When you run a procedurePERSISTENT, its main block executes and then returns to the caller, just as it would without thePERSISTENTkeyword. The difference is that when you run itPERSISTENT, the procedure stays in memory so that you can run internal procedures in it later on. The diagram in Figure 13–4 shows how this works.Figure 13–4: Instantiating a persistent procedure
![]()
The code in Figure 13–4 executes as follows:
MainProc.pRUNsSubProc.pPERSISTENTand saves off its procedure handle in thehProcvariable. The main block ofSubProc.pdefines a variable and then executes the startup code represented by theDOthisand DOthatstatements.- The instantiation of the persistent procedure
SubProc.pis complete. It returns control toMainProc.p, passing back through theSETphrase the procedure handle it’s been given.SubProc.pnow is removed from the call stack. At this point, and for the duration ofMainProc.p, thehProcvariable holds the procedure handle of the running instance ofSubProc.p.You’ll see in the "GET-SIGNATURE method" section how you can make use of this handle.
Now that
SubProc.pis in memory,MainProc.p(or any other procedure with access to its handle) can make use of it by runningh-UsefulProc1andh-UsefulProc2whenever it needs to.Parameters and persistent procedures
You can pass parameters to a persistent procedure just as you can to any other procedure. If you pass
INPUTparameters to it, they are available throughout the life of the persistent procedure. If you passOUTPUTparameters to it, their values are returned to the caller at the end of the persistent procedure’s instantiation. This is represented in Figure 13–4 by the arrow that returns control toMainProc.p. (Here and elsewhere in this discussion, you should understand thatINPUT-OUTPUTparameters have the same characteristics as bothINPUTandOUTPUTparameters where this is concerned.)In practice, you should not normally pass parameters of either kind to a persistent procedure. This is because the best model for using persistent procedures is to initiate them with a
RUNstatement, and then to access the procedure’s contents afterwards with other statements. This is strictly a matter of programming style—there’s nothing wrong with passing parameters per se. Perhaps the best argument for not doing it is that if you instantiate a persistent procedure simply by running it with no parameters, you maximize the flexibility of how you access it. If it has parameters, then you must always be sure to pass the right parameters when you start it up, which can introduce maintenance problems if the parameter list must change.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |